package net.qiqbframework.eventhandling;


import net.qiqbframework.common.BuilderUtils;
import net.qiqbframework.tracing.Span;
import net.qiqbframework.tracing.SpanFactory;

import java.time.Duration;
import java.time.Instant;
import java.util.function.Supplier;

public class DefaultEventProcessorSpanFactory implements EventProcessorSpanFactory {

    private final SpanFactory spanFactory;


    /**
     * Creates a new {@link DefaultEventProcessorSpanFactory} using the provided {@code builder}.
     *
     * @param builder The builder to build the {@link DefaultEventProcessorSpanFactory} from.
     */
    protected DefaultEventProcessorSpanFactory(Builder builder) {
        builder.validate();
        this.spanFactory = builder.builderSpanFactory;

    }


    /**
     * Creates a new {@link Builder} to build a {@link DefaultEventProcessorSpanFactory} with. The default values are:
     * <ul>
     *     <li>{@code disableBatchTrace} defaults to {@code false}</li>
     *     <li>{@code distributedInSameTrace} defaults to {@code false}</li>
     *     <li>{@code distributedInSameTraceTimeLimit} defaults to 2 minutes</li>
     * </ul>
     * The {@code spanFactory} is a required field and should be provided.
     *
     * @return The {@link Builder} to build a {@link DefaultEventProcessorSpanFactory} with.
     */
    public static Builder builder() {
        return new Builder();
    }


    @Override
    public Span createProcessEventSpan(EventMessage<?> eventMessage) {

        Supplier<String> name = () -> "StreamingEventProcessor.process";

        // We have a batch trace, so create a child handler span of that span.
        return spanFactory.createChildHandlerSpan(name, eventMessage);
    }

    /**
     * Builder class to instantiate a {@link DefaultEventProcessorSpanFactory}. The default values are:
     * <ul>
     *     <li>{@code disableBatchTrace} defaults to {@code false}</li>
     *     <li>{@code distributedInSameTrace} defaults to {@code false}</li>
     *     <li>{@code distributedInSameTraceTimeLimit} defaults to 2 minutes</li>
     * </ul>
     * The {@code spanFactory} is a required field and should be provided.
     */
    public static class Builder {

        private SpanFactory builderSpanFactory;


        /**
         * Sets the {@link SpanFactory} to use to create the spans. This is a required field.
         *
         * @param spanFactory The {@link SpanFactory} to use to create the spans.
         * @return The current Builder instance, for fluent interfacing.
         */
        public Builder spanFactory(SpanFactory spanFactory) {
            BuilderUtils.assertNonNull(spanFactory, "spanFactory may not be null");
            this.builderSpanFactory = spanFactory;
            return this;
        }



        protected void validate() {

            BuilderUtils.assertNonNull(builderSpanFactory, "spanFactory may not be null");
        }

        public DefaultEventProcessorSpanFactory build() {
            return new DefaultEventProcessorSpanFactory(this);
        }
    }
}
